package com.huanxing.cloud.upms.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huanxing.cloud.common.core.constant.CommonConstants;
import com.huanxing.cloud.common.core.util.Result;
import com.huanxing.cloud.common.log.annotation.SysLog;
import com.huanxing.cloud.common.myabtis.tenant.HxTenantContextHolder;
import com.huanxing.cloud.upms.service.ISysMenuService;
import com.huanxing.cloud.upms.service.ISysRoleService;
import com.huanxing.cloud.upms.api.entity.SysMenu;
import com.huanxing.cloud.upms.api.vo.MenuVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 菜单管理
 *
 * @author lijx
 * @since 2022/2/26 16:40
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/menu")
@Tag(description = "menu", name = "菜单管理")
public class SysMenuController {

	private final ISysMenuService sysMenuService;

	private final ISysRoleService sysRoleService;

	/**
	 * 获取所有菜单和权限
	 * @return 树形菜单
	 */
	@Operation(summary = "查询树形菜单集合")
	@SaCheckPermission("upms:sysmenu:page")
	@GetMapping(value = "/tree")
	public Result getAllTree() {
		List<SysMenu> sysMenus = sysMenuService.list(Wrappers.<SysMenu>lambdaQuery());
		List<TreeNode<String>> treeNodes = sysMenus.stream()
			.sorted(Comparator.comparingInt(SysMenu::getSort))
			.map(menu -> {
				TreeNode<String> treeNode = new TreeNode<>();
				treeNode.setId(menu.getId());
				treeNode.setParentId(menu.getParentId());
				treeNode.setName(menu.getName());
				treeNode.setWeight(menu.getSort());
				Map<String, Object> extra = new HashMap<>();
				extra.put("icon", menu.getIcon());
				extra.put("type", menu.getType());
				extra.put("createTime", menu.getCreateTime());
				extra.put("permission", menu.getPermission());
				extra.put("path", menu.getPath());
				extra.put("component", menu.getComponent());
				extra.put("applicationKey", menu.getApplicationKey());
				extra.put("sort", menu.getSort());
				treeNode.setExtra(extra);
				return treeNode;
			})
			.collect(Collectors.toList());
		return Result.success(TreeUtil.build(treeNodes, CommonConstants.PARENT_ID));
	}

	@Operation(summary = "查询当前用户的树形菜单集合")
	@GetMapping
	public Result getMenu() {
		Set<MenuVO> all = new HashSet<>();
		List<String> roles = sysRoleService.findRoleIdsByUserId(StpUtil.getLoginId().toString());
		roles.forEach(roleId -> all.addAll(sysMenuService.findMenuByRoleId(roleId)));

		List<TreeNode<String>> treeNodes = all.stream()
			.filter(menuVo -> CommonConstants.MENU_TYPE_0.equals(menuVo.getType()))
			.sorted(Comparator.comparingInt(MenuVO::getSort))
			.map(menu -> {
				TreeNode<String> treeNode = new TreeNode<>();
				treeNode.setId(menu.getId());
				treeNode.setParentId(menu.getParentId());
				treeNode.setName(menu.getName());
				treeNode.setWeight(menu.getSort());
				Map<String, Object> extra = new HashMap<>();
				extra.put("icon", menu.getIcon());
				extra.put("type", menu.getType());
				extra.put("createTime", menu.getCreateTime());
				extra.put("permission", menu.getPermission());
				extra.put("path", menu.getPath());
				extra.put("component", menu.getComponent());
				extra.put("applicationKey", menu.getApplicationKey());
				extra.put("sort", menu.getSort());
				extra.put("redirect", menu.getRedirect());
				treeNode.setExtra(extra);
				return treeNode;
			})
			.collect(Collectors.toList());
		return Result.success(TreeUtil.build(treeNodes, CommonConstants.PARENT_ID));
	}

	@Operation(summary = "查询当前用户的树形菜单集合")
	@GetMapping("/user/tree")
	public Result getUserMenu() {
		Set<MenuVO> all = new HashSet<>();
		List<String> roles = sysRoleService.findRoleIdsByUserId(StpUtil.getLoginId().toString());
		roles.forEach(roleId -> all.addAll(sysMenuService.findMenuByRoleId(roleId)));
		List<TreeNode<String>> treeNodes = all.stream().sorted(Comparator.comparingInt(MenuVO::getSort)).map(menu -> {
			TreeNode<String> treeNode = new TreeNode<>();
			treeNode.setId(menu.getId());
			treeNode.setParentId(menu.getParentId());
			treeNode.setName(menu.getName());
			treeNode.setWeight(menu.getSort());
			Map<String, Object> extra = new HashMap<>();
			extra.put("icon", menu.getIcon());
			extra.put("type", menu.getType());
			extra.put("createTime", menu.getCreateTime());
			extra.put("permission", menu.getPermission());
			extra.put("path", menu.getPath());
			extra.put("component", menu.getComponent());
			extra.put("applicationKey", menu.getApplicationKey());
			extra.put("sort", menu.getSort());
			extra.put("redirect", menu.getRedirect());
			treeNode.setExtra(extra);
			return treeNode;
		}).collect(Collectors.toList());
		return Result.success(TreeUtil.build(treeNodes, CommonConstants.PARENT_ID));
	}

	@Operation(summary = "查询角色的菜单集合")
	@SaCheckPermission("upms:sysmenu:get")
	@GetMapping("/role/tree")
	public Result<List<String>> getRoleMenus(String roleId, String tenantId) {
		if (StrUtil.isNotBlank(tenantId)) {
			HxTenantContextHolder.setTenantId(tenantId);
		}
		return Result
			.success(sysMenuService.findMenuByRoleId(roleId).stream().map(MenuVO::getId).collect(Collectors.toList()));
	}

	@Operation(summary = "通过ID查询")
	@SaCheckPermission("upms:sysmenu:get")
	@GetMapping("/{id}")
	public Result getById(@PathVariable String id) {
		return Result.success(sysMenuService.getById(id));
	}

	@SysLog("新增菜单")
	@Operation(summary = "菜单新增")
	@SaCheckPermission("upms:sysmenu:add")
	@PostMapping
	public Result add(@RequestBody SysMenu sysMenu) {
		return Result.success(sysMenuService.saveMenu(sysMenu));
	}

	@SysLog("编辑菜单")
	@Operation(summary = "菜单编辑")
	@SaCheckPermission("upms:sysmenu:edit")
	@PutMapping
	public Result edit(@RequestBody SysMenu sysMenu) {
		return Result.success(sysMenuService.updateMenuById(sysMenu));
	}

	@SysLog("删除菜单")
	@Operation(summary = "菜单删除")
	@SaCheckPermission("upms:sysmenu:del")
	@DeleteMapping("/{id}")
	public Result del(@PathVariable("id") String id) {
		return Result.success(sysMenuService.removeMenuById(id));
	}

}
